package cc.rengu.igas.mcps.core.service.trans.common;

import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.service.base.InstalQuerySevice;
import cc.rengu.igas.mcps.facade.bean.TransDetail;
import cc.rengu.igas.mcps.facade.request.PosTransDetailQueryRequest;
import cc.rengu.igas.mcps.facade.response.PosTransDetailQueryResponse;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class PosTransDetailQueryService extends InstalQuerySevice {
    @Override
    protected Object bizBeforeCust() throws Exception {
        PosTransDetailQueryRequest posTransDetailQueryRequest = new PosTransDetailQueryRequest();
        ConvertUtil.convertOutput(posTransDetailQueryRequest);
        return posTransDetailQueryRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        PosTransDetailQueryRequest posTransDetailQueryRequest = (PosTransDetailQueryRequest) request;
        PosTransDetailQueryResponse posTransDetailQueryResponse = new PosTransDetailQueryResponse();
        BizResponse bizResponse = new BizResponse();
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        String mchntOrderId = posTransDetailQueryRequest.getOriOrderId();
        List<PayOrderInfo> payOrderInfoList;
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        /*获取交易明细*/
        if (null != posTransDetailQueryRequest.getOriOrderId()) {
            /*判断原商户订单号是否上送 根据订单号查询交易明细*/
            payOrderInfoList = getMchntOrderInfoByOrderId(mchntOrderId, userOrderInfoMapper, payOrderInfoMapper, posTransDetailQueryRequest);
        } else if (null != posTransDetailQueryRequest.getBeginTime() && null != posTransDetailQueryRequest.getEndTime()) {
            /*判断 起止时间是否上送 根据起始时间来查询交易明细*/
            payOrderInfoList = getMchntOrderInfoByTime(mchntOrderId, mchntOrderInfoMapper, payOrderInfoMapper, posTransDetailQueryRequest, bizResponse);
        } else {
            /*获取当月交易明细*/
            payOrderInfoList = getMchntOrderInfoByMonth(mchntOrderId, mchntOrderInfoMapper, payOrderInfoMapper, posTransDetailQueryRequest, bizResponse);
        }
        /*若 查询结果为空*/
        if (null == payOrderInfoList || payOrderInfoList.isEmpty()) {
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            bizResponse.setResult(posTransDetailQueryResponse);
            return bizResponse;
        }
        /*若不为空*/
        /*设置返回报文*/
        posTransDetailQueryResponse = assembleReturnMessage(posTransDetailQueryRequest, payOrderInfoList);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(posTransDetailQueryResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        PosTransDetailQueryResponse posTransDetailQueryResponse = (PosTransDetailQueryResponse) bizResponse.getResult();
        posTransDetailQueryResponse.setRespCode(bizResponse.getRespCode());
        posTransDetailQueryResponse.setRespDesc(bizResponse.getRespDesc());
        ConvertUtil.convertInput(posTransDetailQueryResponse);
    }

    /*根据上传订单号获取订单*/
    private List<PayOrderInfo> getMchntOrderInfoByOrderId(String mchntOrderId, UserOrderInfoMapper userOrderInfoMapper, PayOrderInfoMapper payOrderInfoMapper, PosTransDetailQueryRequest posTransDetailQueryRequest) throws Exception {
        /*根据商户订单号获取用户订单信息*/
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByMchntOrderId(posTransDetailQueryRequest.getHeader().getInstId(), mchntOrderId, posTransDetailQueryRequest.getHeader().getSrcSysId(), posTransDetailQueryRequest.getHeader().getChanlId());
        if (null == userOrderInfo) {
            rglog.error("订单不存在，订单号mchntOrderId输入错误：<{}>", mchntOrderId);
            throw new BizException(RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_INFO_ERROR.getRespDesc());
        }
        /*获取支付订单表*/
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(posTransDetailQueryRequest.getHeader().getInstId(), userOrderInfo.getSysSeqNum());
        if (null == payOrderInfoList || payOrderInfoList.isEmpty()) {
            rglog.error("订单不存在，订单号mchntOrderId输入错误：<{}>", mchntOrderId);
            throw new BizException(RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_INFO_ERROR.getRespDesc());
        }
        /*过滤掉营销、虚拟账户、D0 、支付失败 的订单 获取实际支付订单*/
        payOrderInfoList = payOrderInfoList.stream().filter(item -> !item.getMsgDstId().equals(ChannelEnum.MOMP.getChannelType()) && !item.getMsgDstId().equals(ChannelEnum.ACCT.getChannelType()) && !"9".equals(item.getDstCallIndex()) && (item.getBizStatus().equals(BizStatusEnum.FINISH.getStatus()) || item.getBizStatus().equals(BizStatusEnum.AUTH_COMPLETE.getStatus()))).collect(Collectors.toList());
        if (payOrderInfoList.isEmpty()) {
            rglog.error("实际支付订单不存在或者未支付，订单号mchntOrderId：<{}>", mchntOrderId);
            throw new BizException(RespCodeEnum.GET_PAY_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_INFO_ERROR.getRespDesc());
        }
        return payOrderInfoList;
    }

    /*根据起止时间 终端号商户号 获取交易明细*/
    private List<PayOrderInfo> getMchntOrderInfoByTime(String mchntOrderId, MchntOrderInfoMapper mchntOrderInfoMapper, PayOrderInfoMapper payOrderInfoMapper, PosTransDetailQueryRequest posTransDetailQueryRequest, BizResponse bizResponse) throws Exception {
        List<PayOrderInfo> payOrderInfoList;
        List<PayOrderInfo> payOrderInfoListAll = new ArrayList<>();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = posTransDetailQueryRequest.getHeader().getInstId();
        String termNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_NO);
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        String beginTime = posTransDetailQueryRequest.getBeginTime();
        String endTime = posTransDetailQueryRequest.getEndTime();
        /*根据起止时间从商户订单表或者商户订单历史表中获取商户订单信息*/
        List<MchntOrderInfo> mchntOrderInfoList = mchntOrderInfoMapper.selectMchntOrderInfoByMchntNo(instId, mchntNo, beginTime, endTime);
        /*判断是否为空*/
        if (null == mchntOrderInfoList || mchntOrderInfoList.isEmpty()) {
            rglog.info("该段时间内此终端未发生交易，终端号：<{}> 、起始时间：<{}> 、截止时间:<{}>", termNo, beginTime, endTime);
            bizResponse.setRespDesc(RespCodeEnum.POS_PAYMENT_QURRY_NOT_EXIST.getRespDesc());
            bizResponse.setRespCode(RespCodeEnum.POS_PAYMENT_QURRY_NOT_EXIST.getRespCode());
            return null;
        }
        /*获取支付订单表*/
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
            payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, mchntOrderInfo.getSysSeqNum());
            if (null == payOrderInfoList || payOrderInfoList.isEmpty()) {
                rglog.info("支付订单不存在，订单号mchntOrderId：<{}>", mchntOrderInfo.getMchntOrderId());
                continue;
            }
            /*过滤掉营销、虚拟账户、D0 、支付失败 的订单 获取实际支付订单*/
            payOrderInfoList = payOrderInfoList.stream().filter(item -> !item.getMsgDstId().equals(ChannelEnum.MOMP.getChannelType()) && !item.getMsgDstId().equals(ChannelEnum.ACCT.getChannelType()) && !"9".equals(item.getDstCallIndex()) && (item.getBizStatus().equals(BizStatusEnum.FINISH.getStatus()) || item.getBizStatus().equals(BizStatusEnum.AUTH_COMPLETE.getStatus()))).collect(Collectors.toList());
            if (payOrderInfoList.isEmpty()) {
                rglog.info("实际支付订单不存在或者未支付，订单号mchntOrderId：<{}>", mchntOrderId);
                continue;
            }
            payOrderInfoListAll.add(payOrderInfoList.get(0));
        }
        return payOrderInfoListAll;
    }

    /*获取当月内 改终端 发起的交易详情*/
    private List<PayOrderInfo> getMchntOrderInfoByMonth(String mchntOrderId, MchntOrderInfoMapper mchntOrderInfoMapper, PayOrderInfoMapper payOrderInfoMapper, PosTransDetailQueryRequest posTransDetailQueryRequest, BizResponse bizResponse) throws Exception {
        /*获取一个月内的交易明细 正式表默认存储一个月内的 数据*/
        List<PayOrderInfo> payOrderInfoList;
        List<PayOrderInfo> payOrderInfoListAll = new ArrayList<>();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = posTransDetailQueryRequest.getHeader().getInstId();
        String termNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_NO);
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        List<MchntOrderInfo> mchntOrderInfoList = mchntOrderInfoMapper.selectMchntOrderInfoByMchntNo(instId, mchntNo, DateUtil.getFirstDayOfMonth(), DateUtil.getLastDayOfMonth());
        if ((null == mchntOrderInfoList || mchntOrderInfoList.isEmpty())) {
            rglog.info("当月内此终端未发生交易，终端号：<{}> ", termNo);
            bizResponse.setRespDesc(RespCodeEnum.POS_PAYMENT_QURRY_NOT_EXIST.getRespDesc());
            bizResponse.setRespCode(RespCodeEnum.POS_PAYMENT_QURRY_NOT_EXIST.getRespCode());
            return null;
        }
        /*获取支付订单表*/
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
            payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, mchntOrderInfo.getSysSeqNum());
            if (null == payOrderInfoList || payOrderInfoList.isEmpty()) {
                rglog.info("支付订单不存在，订单号mchntOrderId：<{}>", mchntOrderInfo.getMchntOrderId());
                continue;
            }
            /*过滤掉营销、虚拟账户、D0 、支付失败 的订单 获取实际支付订单*/
            payOrderInfoList = payOrderInfoList.stream().filter(item -> !item.getMsgDstId().equals(ChannelEnum.MOMP.getChannelType()) && !item.getMsgDstId().equals(ChannelEnum.ACCT.getChannelType()) && !"9".equals(item.getDstCallIndex()) && (item.getBizStatus().equals(BizStatusEnum.FINISH.getStatus()) || item.getBizStatus().equals(BizStatusEnum.AUTH_COMPLETE.getStatus()))).collect(Collectors.toList());
            if (payOrderInfoList.isEmpty()) {
                rglog.info("实际支付订单不存在或者未支付，订单号mchntOrderId：<{}>", mchntOrderId);
                continue;
            }
            payOrderInfoListAll.add(payOrderInfoList.get(0));
        }
        return payOrderInfoListAll;
    }

    /*组装返回报文*/
    private PosTransDetailQueryResponse assembleReturnMessage(PosTransDetailQueryRequest posTransDetailQueryRequest, List<PayOrderInfo> payOrderInfoList) {
        PosTransDetailQueryResponse posTransDetailQueryResponse = new PosTransDetailQueryResponse();
        posTransDetailQueryResponse.setHeader(posTransDetailQueryRequest.getHeader());
        posTransDetailQueryResponse.setCount(String.valueOf(payOrderInfoList.size()));
        String itemNum;
        /*设置返回交易信息 list*/
        List<TransDetail> transDetailList = new ArrayList<>();
        /*设置循环节点数*/
        if (null == posTransDetailQueryRequest.getItemNum()) {
            itemNum = "10";
        } else {
            itemNum = posTransDetailQueryRequest.getItemNum();
        }
        /*总数大于请求条数*/
        if (AmountUtil.compare(AmountUtil.addition(posTransDetailQueryRequest.getPackageNo(), itemNum), String.valueOf(payOrderInfoList.size())) == -1) {
            posTransDetailQueryResponse.setListMum(posTransDetailQueryRequest.getItemNum());
            posTransDetailQueryResponse.setEndFlag("N");
            posTransDetailQueryResponse.setPackageNo(AmountUtil.addition(posTransDetailQueryRequest.getPackageNo(), itemNum));
            String maxNum = AmountUtil.addition(posTransDetailQueryRequest.getPackageNo(), itemNum);
            for (int i = Integer.parseInt(posTransDetailQueryRequest.getPackageNo()); i < Integer.parseInt(maxNum); i++) {
                TransDetail transDetail = new TransDetail();
                BeanUtil.beanCopy(payOrderInfoList.get(i), transDetail);
                transDetailList.add(transDetail);
            }
            posTransDetailQueryResponse.setTransDetailList(transDetailList);
        }
        /*总数小于等于请求条数*/
        if (AmountUtil.compare(AmountUtil.addition(posTransDetailQueryRequest.getPackageNo(), itemNum), String.valueOf(payOrderInfoList.size())) == 1 || AmountUtil.compare(AmountUtil.addition(posTransDetailQueryRequest.getPackageNo(), itemNum), String.valueOf(payOrderInfoList.size())) == 0) {
            posTransDetailQueryResponse.setListMum(AmountUtil.subtraction(String.valueOf(payOrderInfoList.size()), posTransDetailQueryRequest.getPackageNo()));
            posTransDetailQueryResponse.setEndFlag("Y");
            posTransDetailQueryResponse.setPackageNo(AmountUtil.addition(posTransDetailQueryRequest.getPackageNo(), posTransDetailQueryResponse.getListMum()));
            for (int i = Integer.parseInt(posTransDetailQueryRequest.getPackageNo()); i < payOrderInfoList.size(); i++) {
                TransDetail transDetail = new TransDetail();
                BeanUtil.beanCopy(payOrderInfoList.get(i), transDetail);
                transDetailList.add(transDetail);
            }
            posTransDetailQueryResponse.setTransDetailList(transDetailList);
        }
        return posTransDetailQueryResponse;
    }
}
